﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace FasterWPF
{
    public static class ImageFlipper
    {
        //@"pack://siteoforigin:,,,/Images/Bldgs1.jpg"
        //@"pack://siteoforigin:,,,/Images/Bldgs2.jpg"
        public static Border CreateImageFlipper(double width, double height, double millisecondsForTimer, Thickness margin, Brush outerBorderBackground, Thickness outerBorderThickness, Brush innerBorderBackground, Thickness innerBorderThickness, Brush footerBackground, double footerHeight, string imageUri, UriKind uriKind, string imageUri2, UriKind uriKind2, double circleWidthHeight, Thickness circleMarginThickness, Brush circleHighlightColor, Brush circleUnHighlighted)
        {
            bool switchTransition = false;
            var observable = Observable.Interval(TimeSpan.FromMilliseconds(millisecondsForTimer)).TimeInterval();
            IDisposable disposableForTimer = null;
            Border xyz = null;

            Border b = new Border();
            b.Margin = margin;
            b.Initialize(width, height, ContainerType.VerticalPanel, outerBorderBackground, outerBorderThickness, footerBackground);
            b.BeginSettings<Border>().Set<Image, Border>(0, 1, "Visibility", Visibility.Collapsed).SetItemBorderSettings(double.NaN, double.NaN, innerBorderBackground, innerBorderThickness).EndSettings();

            b.BeginComposite<Border>()
                .AddImage(0, 0, imageUri, uriKind, width)
                .AddImage(0, 1, imageUri2, uriKind2, width)
                .AddAnyIParent<ContentControl, Border>(0, 2, myIParent =>
                {
                    myIParent.Initialize(width, footerHeight, ContainerType.HorizontalPanel, Brushes.Transparent, new Thickness(0), Brushes.Transparent);

                    myIParent.BeginSettings()
                          .SetItemBorderSettings(double.NaN, double.NaN, Brushes.Transparent, new Thickness(0))
                          .Set<Ellipse, ContentControl>("Fill", circleUnHighlighted)
                          .Set<Ellipse, ContentControl>("Height", circleWidthHeight)
                          .Set<Ellipse, ContentControl>("Margin", circleMarginThickness)
                          .Set<Ellipse, ContentControl>("Width", circleWidthHeight).EndSettings();

                    xyz = myIParent.BeginComposite()
                        .AddAnything<Ellipse, ContentControl>(0, 0)
                        .AddAnything<Ellipse, ContentControl>(0, 1)
                        .SubscribeEventOnChild<Ellipse, ContentControl, MouseButtonEventArgs>(0, 0, "PreviewMouseDown", ((o, e) =>
                        {
                            //stop image transitions
                            switchTransition = true;
                            if (disposableForTimer != null)
                            {
                                disposableForTimer.Dispose();
                            }
                            (o as Ellipse).Fill = circleHighlightColor;
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                            }
                            b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Visible; });
                            b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });
                        }))
                        .SubscribeEventOnChild<Ellipse, ContentControl, MouseButtonEventArgs>(0, 1, "PreviewMouseDown", ((o, e) =>
                        {
                            //stop image transitions
                            switchTransition = false;
                            if (disposableForTimer != null)
                            {
                                disposableForTimer.Dispose();
                            }
                            (o as Ellipse).Fill = circleHighlightColor;
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                            }
                            b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                            b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Visible; });
                        }))
                        .EndComposite<ContentControl, ContentControlArgs>(null);
                })
                 .EndComposite<Border, BorderArgs>(null);

            //starting colors
            if (xyz != null)
            {
                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleHighlightColor;
                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
            }

            //Display for 3000 milliseconds, then transition
            disposableForTimer = observable.Subscribe(t =>
            {
                FasterWPF.AnimationExt.RunInUiThread(b.Dispatcher, () =>
                {
                    if (switchTransition)
                    {
                        b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Visible; });
                        b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });

                        if (xyz != null)
                        {
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleHighlightColor;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                        }
                        switchTransition = false;
                    }
                    else
                    {
                        b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                        b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Visible; });
                        if (xyz != null)
                        {
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleHighlightColor;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                        }
                        switchTransition = true;
                    }
                });

            });

            return b;
        }


        public static Border CreateImageFlipper(double width, double height, double millisecondsForTimer, Thickness margin, Brush outerBorderBackground, Thickness outerBorderThickness, Brush innerBorderBackground, Thickness innerBorderThickness, Brush footerBackground, double footerHeight, string imageUri, UriKind uriKind, string imageUri2, UriKind uriKind2, string imageUri3, UriKind uriKind3, double circleWidthHeight, Thickness circleMarginThickness, Brush circleHighlightColor, Brush circleUnHighlighted)
        {
            int switchTransition = 0;
            var observable = Observable.Interval(TimeSpan.FromMilliseconds(millisecondsForTimer)).TimeInterval();
            Border xyz = null;
            IDisposable disposer = null;

            Border b = new Border();
            b.Margin = margin;
            b.Initialize(width, height, ContainerType.VerticalPanel, outerBorderBackground, outerBorderThickness, footerBackground);
            b.BeginSettings<Border>().Set<Image, Border>(0, 1, "Visibility", Visibility.Collapsed).SetItemBorderSettings(double.NaN, double.NaN, innerBorderBackground, innerBorderThickness).EndSettings();

            b.BeginComposite<Border>()
                .AddImage(0, 0, imageUri, uriKind, width)
                .AddImage(0, 1, imageUri2, uriKind2, width)
                .AddImage(0, 2, imageUri3, uriKind3, width)
                .AddAnyIParent<ContentControl, Border>(0, 3, myIParent =>
                {
                    myIParent.Initialize(width, footerHeight, ContainerType.HorizontalPanel, Brushes.Transparent, new Thickness(0), Brushes.Transparent);

                    myIParent.BeginSettings()
                          .SetItemBorderSettings(double.NaN, double.NaN, Brushes.Transparent, new Thickness(0))
                          .Set<Ellipse, ContentControl>("Fill", circleUnHighlighted)
                          .Set<Ellipse, ContentControl>("Height", circleWidthHeight)
                          .Set<Ellipse, ContentControl>("Margin", circleMarginThickness)
                          .Set<Ellipse, ContentControl>("Width", circleWidthHeight).EndSettings();

                    xyz = myIParent.BeginComposite()
                        .AddAnything<Ellipse, ContentControl>(0, 0)
                        .AddAnything<Ellipse, ContentControl>(0, 1)
                        .AddAnything<Ellipse, ContentControl>(0, 2)
                        .SubscribeEventOnChild<Ellipse, ContentControl, MouseButtonEventArgs>(0, 0, "PreviewMouseDown", ((o, e) =>
                        {
                            //stop image transitions
                            switchTransition = 1;
                            if (disposer != null)
                            {
                                disposer.Dispose();
                            }
                            (o as Ellipse).Fill = circleHighlightColor;
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                            }
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleUnHighlighted;
                            }
                            b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Visible; });
                            b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });
                            b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Collapsed; });
                        }))
                        .SubscribeEventOnChild<Ellipse, ContentControl, MouseButtonEventArgs>(0, 1, "PreviewMouseDown", ((o, e) =>
                        {
                            //stop image transitions
                            switchTransition = 2;
                            if (disposer != null)
                            {
                                disposer.Dispose();
                            }
                            (o as Ellipse).Fill = circleHighlightColor;
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                            }
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleUnHighlighted;
                            }
                            b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                            b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Visible; });
                            b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Collapsed; });
                        }))
                        .SubscribeEventOnChild<Ellipse, ContentControl, MouseButtonEventArgs>(0, 2, "PreviewMouseDown", ((o, e) =>
                        {
                            //stop image transitions
                            switchTransition = 0;
                            if (disposer != null)
                            {
                                disposer.Dispose();
                            }
                            (o as Ellipse).Fill = circleHighlightColor;
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                            }
                            if (xyz != null)
                            {
                                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                            }
                            b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                            b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });
                            b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Visible; });
                        }))
                        .EndComposite<ContentControl, ContentControlArgs>(null);
                })
                 .EndComposite<Border, BorderArgs>(null);

            //starting colors
            if (xyz != null)
            {
                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleHighlightColor;
                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleUnHighlighted;
            }

            //Display for so many milliseconds, then transition
            disposer = observable.Subscribe(t =>
            {
                FasterWPF.AnimationExt.RunInUiThread(b.Dispatcher, () =>
                {
                    if (switchTransition == 0)
                    {
                        b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Visible; });
                        b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });
                        b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Collapsed; });

                        if (xyz != null)
                        {
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleHighlightColor;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleUnHighlighted;
                        }
                        switchTransition = 1;
                    }
                    else if (switchTransition == 1)
                    {
                        b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                        b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Visible; });
                        b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Collapsed; });

                        if (xyz != null)
                        {
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleHighlightColor;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleUnHighlighted;
                        }
                        switchTransition = 2;
                    }
                    else
                    {
                        b.UpdateImages(0, 0, img => { img.Visibility = Visibility.Collapsed; });
                        b.UpdateImages(0, 1, img => { img.Visibility = Visibility.Collapsed; });
                        b.UpdateImages(0, 2, img => { img.Visibility = Visibility.Visible; });

                        if (xyz != null)
                        {
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 2).Fill = circleHighlightColor;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 0).Fill = circleUnHighlighted;
                            xyz.GetChildFromComposite<Ellipse, ContentControl>(0, 1).Fill = circleUnHighlighted;
                        }
                        switchTransition = 0;
                    }
                });

            });

            return b;
        }
    }//end of class
}//end of namespace
